using System;
using System.Collections.Generic;
using Habanero.Base;
using Habanero.Base.Exceptions;
using Habanero.BO;
using Habanero.BO.ClassDefinition;
using Habanero.UI.Base;
using Habanero.UI.VWG;
using Habanero.UI.Win;
using Habanero.Util;
using NUnit.Framework;

namespace Habanero.Test.UI.Base.Mappers
{
    [TestFixture]
    public class TestCollectionComboBoxMapperVWG
    {

        protected DataStoreInMemory _store;

        //TODO: Add autoselect first property and include blank to constructor
        //TODO: If add item to BOCollection them must update combo box.
        protected virtual IControlFactory GetControlFactory()
        {
            ControlFactoryVWG factory = new ControlFactoryVWG();
            GlobalUIRegistry.ControlFactory = factory;
            return factory;
        }
#pragma warning disable 168
        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            _store = new DataStoreInMemory();
            BORegistry.DataAccessor = new DataAccessorInMemory(_store);
            Dictionary<string, string> collection = Sample.BOLookupCollection;
        }
#pragma warning restore 168

        [Test]
        public void TestConstructor()
        {
            //---------------Set up test pack-------------------
            IComboBox cmbox = GetControlFactory().CreateComboBox();
            //---------------Execute Test ----------------------
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());

            //---------------Test Result -----------------------
            Assert.AreSame(cmbox, mapper.Control);
            Assert.AreSame(propName, mapper.PropertyName);
            Assert.IsFalse(mapper.IsReadOnly);
        }

        [Test]
        public void TestSetBOCollection()
        {
            //---------------Set up test pack-------------------
            IComboBox cmbox = GetControlFactory().CreateComboBox();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());

            Sample bo = new Sample();
            IBusinessObjectCollection col = new BusinessObjectCollection<Sample> { bo };
            //---------------Assert Precondition ---------------
            Assert.AreEqual(0, cmbox.Items.Count);
            //---------------Execute Test ----------------------
            mapper.BusinessObjectCollection = col;
            //---------------Test Result -----------------------
            Assert.AreEqual(2, cmbox.Items.Count, "The Sample item and the blank");
            Assert.AreSame(typeof(string), cmbox.Items[0].GetType(), "First Item should be blank");
            Assert.IsTrue(cmbox.Items.Contains(bo), "Second Item should be the Business Object");
        }

        [Test]
        public void TestSetBusinessObj_ShouldSetTheSelectedItemToCorrectRelatedCar()
        {
            //---------------Set up test pack-------------------
            IComboBox cmbox = GetControlFactory().CreateComboBox();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());

            Car car1; Car car2;
            mapper.BusinessObjectCollection = GetCollectionWithTwoCars(out car1, out car2);
            Sample s = new Sample { SampleLookupID = car1.CarID };
            //---------------Assert Precondition----------------
            Assert.AreEqual(2, mapper.BusinessObjectCollection.Count);
            Assert.AreEqual(3, cmbox.Items.Count);
            Assert.IsNull(cmbox.SelectedItem);
            //---------------Execute Test ----------------------
            mapper.BusinessObject = s;
            //---------------Test Result -----------------------
            Assert.IsNotNull(cmbox.SelectedItem);
            Assert.AreEqual(car1, cmbox.SelectedItem, "Combo Box selected item is not set.");
            Assert.AreEqual(s.SampleLookupID.ToString(), cmbox.SelectedValue.ToString(), "Combo Box Value is not set");
        }

        //This test is specific for VWG where you do not want the BO updated on every event.
        [Test]
        public virtual void TestChangeComboBoxDoesntUpdateBusinessObject()
        {
            //---------------Set up test pack-------------------
            IComboBox cmbox = GetControlFactory().CreateComboBox();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());

            Car car1; Car car2;
            mapper.BusinessObjectCollection = GetCollectionWithTwoCars(out car1, out car2);
            Sample s = new Sample { SampleLookupID = car1.CarID };
            mapper.BusinessObject = s;
            //---------------Execute Test ----------------------
            cmbox.SelectedItem = car2;
            //---------------Test Result -----------------------
            Assert.AreEqual(car1.CarID.ToString(), s.SampleLookupID.ToString());
        }

        protected static BusinessObjectCollection<Car> GetCollectionWithTwoCars(out Car car1, out Car car2)
        {
            car1 = new Car();
            car2 = new Car();
            return new BusinessObjectCollection<Car> { car1, car2 };
        }


        [Test]
        public void Test_ResetBusinessObj_WhenHasNullValueForProperty_WhenPreviousBOHadAValue_ShouldSetSelectedItemNull_BUGFIX()
        {
            //---------------Set up test pack-------------------
            IComboBox cmbox = GetControlFactory().CreateComboBox();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());

            Car car1; Car car2;
            mapper.BusinessObjectCollection = GetCollectionWithTwoCars(out car1, out car2);
            Sample s = new Sample { SampleLookupID = car1.CarID };

            mapper.BusinessObject = s;
            Sample sWithNullPropValue = new Sample();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(cmbox.SelectedItem);
            Assert.AreEqual(car1, cmbox.SelectedItem, "Combo Box selected item is not set.");
            Assert.AreEqual(s.SampleLookupID.ToString(), cmbox.SelectedValue.ToString(), "Combo Box Value is not set");

            Assert.IsNull(sWithNullPropValue.SampleLookupID);
            //---------------Execute Test ----------------------
            mapper.BusinessObject = sWithNullPropValue;
            //---------------Test Result -----------------------
            //            Assert.IsNull(cmbox.SelectedItem);
            TestUtil.AssertStringEmpty(Convert.ToString(cmbox.SelectedItem), "cmbox.SelectedItem", "there should be no item selected");
        }
        [Test]
        public void Test_setBusinessObj_WhenHasNullCollection_ShouldNotRaiseErrro()
        {
            //---------------Set up test pack-------------------
            IComboBox cmbox = GetControlFactory().CreateComboBox();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());

            mapper.BusinessObjectCollection = null;
            Car car1 = new Car();
            Sample s = new Sample { SampleLookupID = car1.CarID };
            //---------------Assert Precondition----------------
            Assert.IsNull(cmbox.SelectedItem);
            Assert.IsNull(mapper.BusinessObjectCollection);
            //---------------Execute Test ----------------------
            try
            {
                mapper.BusinessObject = s;
                Assert.Fail("expected developer exception");
            }
            //---------------Test Result -----------------------
            catch (HabaneroDeveloperException ex)
            {
                StringAssert.Contains("The BusinessObjectCollection is null when in the CollectionComboBoxMapper when the BusinessObject is set ", ex.Message);
                StringAssert.Contains("The BusinessObjectCollection is null when in the CollectionComboBoxMapper when the BusinessObject is set ", ex.DeveloperMessage);
            }

        }


        [Test]
        public void TestSetBusinessObject_Null_DoesNotRaiseError_BUGFIX()
        {
            //---------------Set up test pack-------------------
            IComboBox cmbox = GetControlFactory().CreateComboBox();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());
            Car car1; Car car2;
            mapper.BusinessObjectCollection = GetCollectionWithTwoCars(out car1, out car2);
            //---------------Assert Precondition----------------
            Assert.IsNull(cmbox.SelectedItem);
            //---------------Execute Test ----------------------
            mapper.BusinessObject = null;
            //---------------Test Result -----------------------
            Assert.IsTrue(string.IsNullOrEmpty(Convert.ToString(cmbox.SelectedItem)));
        }

        [Test]
        public void TestSetBusinessObject_Null_NullLookupListSet_DoesNotRaiseError_BUGFIX()
        {
            //---------------Set up test pack-------------------
            IComboBox cmbox = GetControlFactory().CreateComboBox();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());
            //---------------Assert Precondition----------------
            Assert.IsNull(mapper.BusinessObjectCollection);
            Assert.AreEqual(0, cmbox.Items.Count);
            Assert.IsNull(cmbox.SelectedItem);
            //---------------Execute Test ----------------------
            mapper.BusinessObject = null;
            //---------------Test Result -----------------------
            Assert.IsNull(cmbox.SelectedItem);
            Assert.AreEqual(0, cmbox.Items.Count, "Should have only the null item in it.");
        }

        //        //        protected static string GuidToUpper(Guid guid)
        //        //        {
        //        //            return guid.ToString("B").ToUpperInvariant();
        //        //        }
        //        protected static object GetGuidValue(IDictionary<string, string> collection, string lookupItem)
        //        {
        //            BOPropGuidDataMapper guidDataMapper = new BOPropGuidDataMapper();
        //            object returnValue;
        //            guidDataMapper.TryParsePropValue(collection[lookupItem], out returnValue);
        //            return returnValue;
        //        }

        [Test]
        public void TestApplyChangesToBusObj()
        {
            //---------------Set up test pack-------------------
            IComboBox cmbox = GetControlFactory().CreateComboBox();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());
            Car car1; Car car2;
            mapper.BusinessObjectCollection = GetCollectionWithTwoCars(out car1, out car2);
            Sample s = new Sample { SampleLookupID = car1.CarID };
            mapper.BusinessObject = s;
            //---------------Execute Test ----------------------
            cmbox.SelectedItem = car2;
            mapper.ApplyChangesToBusinessObject();
            //---------------Test Result -----------------------
            //            Assert.AreEqual((Guid) Sample.LookupCollection[LOOKUP_ITEM_2], s.SampleLookupID);
            Assert.AreEqual(car2.CarID, s.SampleLookupID);
        }


        //        private static Dictionary<string, string> getLookupList()
        //        {
        //            Sample sample1 = new Sample();
        //            sample1.Save();
        //            Sample sample2 = new Sample();
        //            sample2.Save();
        //            Sample sample3 = new Sample();
        //            sample3.Save();
        //            return new Dictionary<string, string>
        //                                {
        //                                    {"Test3", sample3.ID.GetAsValue().ToString()},
        //                                    {"Test2", sample2.ID.GetAsValue().ToString()},
        //                                    {"Test1", sample1.ID.GetAsValue().ToString()}
        //                                };
        //        }


        [Test]
        public void Test_LookupList_AddItemToComboBox_SelectAdditionalItem_SetsBOPropValueToNull()
        {
            //---------------Set up test pack-------------------
            IComboBox cmbox = GetControlFactory().CreateComboBox();
            const string propName = "SampleLookup2ID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());
            Car car1; Car car2;
            mapper.BusinessObjectCollection = GetCollectionWithTwoCars(out car1, out car2);
            Sample sample = new Sample { SampleLookupID = car1.CarID };
            mapper.BusinessObject = sample;
            cmbox.Items.Add("SomeItem");
            //---------------Assert Preconditions---------------
            Assert.AreEqual(4, cmbox.Items.Count);
            Assert.AreEqual("SomeItem", LastComboBoxItem(cmbox).ToString());
            //---------------Execute Test ----------------------
            cmbox.SelectedIndex = cmbox.Items.Count - 1;
            mapper.ApplyChangesToBusinessObject();
            //---------------Test Result -----------------------
            object value = sample.GetPropertyValue(propName);
            Assert.IsNull(value);
        }
        private static object LastComboBoxItem(IComboBox cmbox)
        {
            return cmbox.Items[cmbox.Items.Count - 1];
        }

    }

    [TestFixture]
    public class TestCollectionComboBoxMapperWin : TestCollectionComboBoxMapperVWG
    {
        protected override IControlFactory GetControlFactory()
        {
            ControlFactoryWin factory = new ControlFactoryWin();
            GlobalUIRegistry.ControlFactory = factory;
            return factory;
        }

        [Test]
        public void TestChangePropValueUpdatesBusObj()
        {
            //---------------Set up test pack-------------------
            IComboBox cmbox = GetControlFactory().CreateComboBox();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, true, GetControlFactory());
            Car car1; Car car2;
            mapper.BusinessObjectCollection = GetCollectionWithTwoCars(out car1, out car2);
            Sample s = new Sample { SampleLookupID = car1.CarID };
            mapper.BusinessObject = s;
            //---------------Test Preconditions-------------------
            Assert.AreEqual(3, Sample.LookupCollection.Count);
            Assert.IsNotNull(mapper.BusinessObjectCollection);
            Assert.IsNotNull(cmbox.SelectedItem, "There should be a selected item to start with");
            //---------------Execute Test ----------------------
            s.SampleLookupID = car2.CarID;
            mapper.UpdateControlValueFromBusinessObject();

            //---------------Test Result -----------------------
            Assert.IsNotNull(cmbox.SelectedItem);
            Assert.AreEqual(s.SampleLookupID.ToString(), cmbox.SelectedItem.ToString(), "Value is not set after changing bo prop Value");
        }

        [Test]
        public void TestChangePropValueUpdatesBusObj_WithoutCallingUpdateControlValue()
        {
            //---------------Set up test pack-------------------
            IComboBox cmbox = GetControlFactory().CreateComboBox();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());
            Car car1; Car car2;
            mapper.BusinessObjectCollection = GetCollectionWithTwoCars(out car1, out car2);
            Sample s = new Sample { SampleLookupID = car1.CarID };
            mapper.BusinessObject = s;
            //---------------Execute Test ----------------------

            s.SampleLookupID = car2.CarID;

            //---------------Test Result -----------------------
            Assert.IsNotNull(cmbox.SelectedItem);
            Assert.AreEqual(s.SampleLookupID.ToString(), cmbox.SelectedItem.ToString(), "Value is not set after changing bo prop Value");
        }

        [Test]
        public override void TestChangeComboBoxDoesntUpdateBusinessObject()
        {
            //For Windows the value should is changed (see TestChangeComboBox_UpdatesBusinessObject).
        }

        [Test]
        public void TestChangeComboBox_UpdatesBusinessObject()
        {
            //For Windows the value should be changed.
            //---------------Set up test pack-------------------
            IComboBox cmbox = GetControlFactory().CreateComboBox();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());
            Car car1; Car car2;
            mapper.BusinessObjectCollection = GetCollectionWithTwoCars(out car1, out car2);
            Sample s = new Sample { SampleLookupID = car1.CarID };
            mapper.BusinessObject = s;
            //---------------Execute Test ----------------------
            cmbox.SelectedItem = car2;
            //---------------Test Result -----------------------
            Assert.AreEqual(car2.CarID.ToString(), s.SampleLookupID.ToString(), "For Windows the value should be changed");
        }

        //        private static Dictionary<string, string> GetLookupList()
        //        {
        //            Sample sample1 = new Sample();
        //            sample1.Save();
        //            Sample sample2 = new Sample();
        //            sample2.Save();
        //            Sample sample3 = new Sample();
        //            sample3.Save();
        //            return new Dictionary<string, string>
        //                        {
        //                            {"Test3", sample3.ID.GetAsValue().ToString()},
        //                            {"Test2", sample2.ID.GetAsValue().ToString()},
        //                            {"Test1", sample1.ID.GetAsValue().ToString()}
        //                        };
        //        }
        //
        //
        [Test]
        public void TestKeyPressEventUpdatesBusinessObject_WithoutCallingApplyChanges()
        {
            //---------------Set up test pack-------------------
            ComboBoxWinStub cmbox = new ComboBoxWinStub();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());
            Car car1; Car car2;
            mapper.BusinessObjectCollection = GetCollectionWithTwoCars(out car1, out car2);
            Sample s = new Sample { SampleLookupID = car1.CarID };
            mapper.BusinessObject = s;
            //---------------Execute Test ----------------------
            cmbox.Text = car2.ToString();
            //---------------Test Result -----------------------
            Assert.IsInstanceOfType(typeof(ComboBoxDefaultMapperStrategyWin), mapper.MapperStrategy);
            Assert.AreEqual(car2.CarID, s.SampleLookupID);
        }

        [Test]
        public void Test_KeyPressStrategy_UpdatesBusinessObject_WhenEnterKeyPressed()
        {
            //---------------Set up test pack-------------------
            ComboBoxWinStub cmbox = new ComboBoxWinStub();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory())
            {
                MapperStrategy =
                    GetControlFactory().CreateLookupKeyPressMapperStrategy()
            };
            Car car1; Car car2;
            mapper.BusinessObjectCollection = GetCollectionWithTwoCars(out car1, out car2);
            Sample s = new Sample { SampleLookupID = car1.CarID };
            mapper.BusinessObject = s;
            //---------------Execute Test ----------------------
            cmbox.Text = car2.ToString();
            cmbox.CallSendKeyBob();
            //---------------Test Result -----------------------
            Assert.IsInstanceOfType(typeof(ComboBoxKeyPressMapperStrategyWin), mapper.MapperStrategy);
            Assert.AreEqual(car2.CarID, s.SampleLookupID);
        }


        [Test]
        public void Test_KeyPressStrategy_DoesNotUpdateBusinessObject_SelectedIndexChanged()
        {
            //---------------Set up test pack-------------------
            ComboBoxWinStub cmbox = new ComboBoxWinStub();
            const string propName = "SampleLookupID";
            CollectionComboBoxMapper mapper = new CollectionComboBoxMapper(cmbox, propName, false, GetControlFactory());
            mapper.MapperStrategy = GetControlFactory().CreateLookupKeyPressMapperStrategy();
            Car car1; Car car2;
            mapper.BusinessObjectCollection = GetCollectionWithTwoCars(out car1, out car2);
            Sample s = new Sample { SampleLookupID = car1.CarID };
            mapper.BusinessObject = s;
            //---------------Execute Test ----------------------
            cmbox.SelectedItem = car2;

            //---------------Test Result -----------------------
            Assert.IsInstanceOfType(typeof(ComboBoxKeyPressMapperStrategyWin), mapper.MapperStrategy);
            Assert.AreEqual(car1.CarID, s.SampleLookupID);
        }

        private class ComboBoxWinStub : ComboBoxWin
        {
            public void CallSendKeyBob()
            {
                this.OnKeyPress(new System.Windows.Forms.KeyPressEventArgs((char)13));
            }
        }
    }

    //    internal class CustomAddCollectionComboBoxMapperStub : CollectionComboBoxMapper
    //    {
    //        public CustomAddCollectionComboBoxMapperStub(IComboBox cbx, string propName, bool isReadOnly,
    //                                                     IControlFactory factory)
    //            : base(cbx, propName, isReadOnly, factory)
    //        {
    //        }
    //
    //        protected override void CustomiseLookupList(Dictionary<string, string> col)
    //        {
    //            Sample additionalBO = new Sample {SampleText = "ExtraLookupItem"};
    //            col.Add(additionalBO.SampleText, additionalBO.ToString());
    //        }
    //    }
    //
    //    internal class CustomRemoveCollectionComboBoxMapperStub : CollectionComboBoxMapper
    //    {
    //        public CustomRemoveCollectionComboBoxMapperStub(IComboBox cbx, string propName, bool isReadOnly,
    //                                                        IControlFactory factory)
    //            : base(cbx, propName, isReadOnly, factory)
    //        {
    //        }
    //
    //        protected override void CustomiseLookupList(Dictionary<string, string> col)
    //        {
    //            string lastKey = "";
    //            foreach (string key in col.Keys)
    //            {
    //                lastKey = key;
    //            }
    //
    //            col.Remove(lastKey);
    //        }
    //    }

    public class CollectionComboBoxMapper : ControlMapper, IComboBoxMapper
    {
        /// <summary>
        /// The actual <see cref="IComboBox"/> control that is being mapped to the Business Object Property identified by PropertyName.
        /// </summary>
        protected IComboBox _comboBox;
        private IComboBoxMapperStrategy _mapperStrategy;

        private IBusinessObjectCollection _businessObjectCollection;
        private readonly ComboBoxCollectionSelector _comboBoxCollectionSelector;

        /// <summary>
        /// Gets or sets the KeyPress event handler assigned to this mapper
        /// </summary>
        public EventHandler KeyPressHandler { get; set; }

        /// <summary>
        /// Gets or sets the SelectedIndexChanged event handler assigned to this mapper
        /// </summary>
        public EventHandler SelectedIndexChangedHandler { get; set; }

        /// <summary>
        /// Constructor to initialise the mapper
        /// </summary>
        /// <param name="cbx">The ComboBox to map</param>
        /// <param name="propName">The property name</param>
        /// <param name="isReadOnly">Whether this control is read only</param>
        /// <param name="factory">The control factory to be used when creating the controlMapperStrategy</param>
        public CollectionComboBoxMapper(IComboBox cbx, string propName, bool isReadOnly, IControlFactory factory)
            : base(cbx, propName, isReadOnly, factory)
        {
            _comboBox = cbx;
            _mapperStrategy = factory.CreateLookupComboBoxDefaultMapperStrategy();
            _mapperStrategy.AddHandlers(this);
            _comboBoxCollectionSelector = new ComboBoxCollectionSelector(cbx, factory, false);
        }


        /// <summary>
        /// Gets or sets the strategy assigned to this mapper <see cref="IComboBoxMapperStrategy"/>
        /// </summary>
        public IComboBoxMapperStrategy MapperStrategy
        {
            get { return _mapperStrategy; }
            set
            {
                _mapperStrategy = value;
                _mapperStrategy.RemoveCurrentHandlers(this);
                _mapperStrategy.AddHandlers(this);
            }
        }


        public IBusinessObjectCollection BusinessObjectCollection
        {
            get { return _businessObjectCollection; }
            set
            {
                _businessObjectCollection = value;
                _comboBoxCollectionSelector.SetCollection(value, true);
            }
        }


        /// <summary>
        /// This is a hack that allows Extended Combo box mapper to use Lookup ComboBox mapper code
        ///  without having to inherit from it.
        /// </summary>
        internal void DoUpdateControlValueFromBO()
        {
            this.InternalUpdateControlValueFromBo();
        }

        /// <summary>
        /// Updates the value on the control from the corresponding property
        /// on the represented <see cref="IControlMapper.BusinessObject"/>
        /// </summary>
        protected override void InternalUpdateControlValueFromBo()
        {
            if (BusinessObjectCollection == null && this.BusinessObject != null)
            {
                const string message = "The BusinessObjectCollection is null when in the CollectionComboBoxMapper when the BusinessObject is set ";
                throw new HabaneroDeveloperException(message, message);
            }
            if (PropertyHasAValue())
            {
                SetValueFromLookupList();
            }
            else
            {
                ClearComboBox();
            }
        }

        private void ClearComboBox()
        {
            _comboBox.SelectedIndex = -1;
            _comboBox.Text = "";
        }

        private bool PropertyHasAValue()
        {
            return !string.IsNullOrEmpty(Convert.ToString(GetPropertyValue()));
        }

        /// <summary>
        /// Populates the ComboBox's list of items using the
        /// strings provided by the colleciton
        /// </summary>
        private void SetValueFromLookupList()
        {
            try
            {
                object boPropertyValue = GetPropertyValue();
                foreach (IBusinessObject bo in this.BusinessObjectCollection)
                {
                    if (bo == null) continue;

                    bool found = bo.ID.ToString().Equals(Convert.ToString(boPropertyValue));
                    if (found)
                    {
                        _comboBox.SelectedItem = bo;
                        break;
                    }
                }
            }
            catch (ObjectDisposedException)
            {
            }
        }


        /// <summary>
        /// Returns the property value of the business object being mapped
        /// </summary>
        /// <returns>Returns the property value in appropriate object form</returns>
        protected override object GetPropertyValue()
        {
            if (IsPropertyVirtual())
            {
                return base.GetPropertyValue();
            }
            return _businessObject == null
                       ? null
                       : _businessObject.GetPropertyValueString(_propertyName);
        }


        /// <summary>
        /// Initialises the control using the attributes already provided, using
        /// <see cref="ControlMapper.SetPropertyAttributes"/>.
        /// </summary>
        protected override void InitialiseWithAttributes()
        {
            if (_attributes["rightClickEnabled"] != null)
            {
                string rightClickEnabled = (string)_attributes["rightClickEnabled"];
                if (rightClickEnabled != "true" && rightClickEnabled != "false")
                {
                    throw new InvalidXmlDefinitionException("An error " +
                                                            "occurred while reading the 'rightClickEnabled' parameter " +
                                                            "from the class definitions.  The 'value' " +
                                                            "attribute must hold either 'true' or 'false'.");
                }
            }
        }

        /// <summary>
        /// Updates the properties on the represented business object
        /// </summary>
        public override void ApplyChangesToBusinessObject()
        {
            //            if (_businessObject == null || _comboBox.SelectedIndex == -1) return;
            IBusinessObject selectedOption = _comboBox.SelectedItem as IBusinessObject;
            if (selectedOption == null) return;
            object newValue = selectedOption.ID.GetAsGuid();
            SetPropertyValue(newValue);
        }
    }
}